Generated by Cython 3.0.2

Yellow lines hint at Python interaction.
Click on a line that starts with a "+" to see the C code that Cython generated for it.

Raw output: interpolation_nearest_neighbor.c

+001: # cython: infer_types=True, wraparound=False, nonecheck=False, boundscheck=False, cdivision=True, language_level=3, profile=False, autogen_pxd=True
  __pyx_t_4 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_4) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 002: 
+003: import numpy as np
  __pyx_t_7 = __Pyx_ImportDottedModule(__pyx_n_s_numpy, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_7) < 0) __PYX_ERR(0, 3, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 004: 
 005: cimport numpy as np
 006: from libc.math cimport atan2, cos, exp, hypot, log, pi, sin
 007: 
 008: from cython.parallel import prange
 009: 
 010: 
 011: # nearest-neighbor interpolation of a 2D array
+012: cdef double _interpolate(float[:,:] image, double x, double y) nogil:
static double __pyx_f_7nanopyx_4core_9transform_30interpolation_nearest_neighbor__interpolate(__Pyx_memviewslice __pyx_v_image, double __pyx_v_x, double __pyx_v_y) {
  int __pyx_v_w;
  int __pyx_v_h;
  int __pyx_v_x0;
  int __pyx_v_y0;
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
 013:     """
 014:     Interpolate a 2D array using nearest-neighbor interpolation
 015:     :param image: 2D array to interpolate
 016:     :param x: x position to interpolate
 017:     :param y: y position to interpolate
 018:     :return: interpolated value
 019:     """
 020: 
+021:     cdef int w = image.shape[1]
  __pyx_v_w = (__pyx_v_image.shape[1]);
+022:     cdef int h = image.shape[0]
  __pyx_v_h = (__pyx_v_image.shape[0]);
 023: 
 024:     # return 0 if x OR y positions do not exist in image
+025:     if not 0 <= x < w or not 0 <= y < h:
  __pyx_t_2 = (0.0 <= __pyx_v_x);
  if (__pyx_t_2) {
    __pyx_t_2 = (__pyx_v_x < __pyx_v_w);
  }
  __pyx_t_3 = (!__pyx_t_2);
  if (!__pyx_t_3) {
  } else {
    __pyx_t_1 = __pyx_t_3;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_3 = (0.0 <= __pyx_v_y);
  if (__pyx_t_3) {
    __pyx_t_3 = (__pyx_v_y < __pyx_v_h);
  }
  __pyx_t_2 = (!__pyx_t_3);
  __pyx_t_1 = __pyx_t_2;
  __pyx_L4_bool_binop_done:;
  if (__pyx_t_1) {
/* … */
  }
+026:         return 0
    __pyx_r = 0.0;
    goto __pyx_L0;
 027: 
+028:     cdef int x0 = int(x)
  __pyx_v_x0 = ((int)__pyx_v_x);
+029:     cdef int y0 = int(y)
  __pyx_v_y0 = ((int)__pyx_v_y);
 030: 
+031:     return image[y0, x0]
  __pyx_t_4 = __pyx_v_y0;
  __pyx_t_5 = __pyx_v_x0;
  __pyx_r = (*((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_image.data + __pyx_t_4 * __pyx_v_image.strides[0]) ) + __pyx_t_5 * __pyx_v_image.strides[1]) )));
  goto __pyx_L0;
 032: 
 033: 
+034: cdef class Interpolator:
struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator {
  float (*_interpolate)(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *, float, float);
  __Pyx_memviewslice (*_magnify)(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *, float);
  __Pyx_memviewslice (*_magnify_xy)(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *, float, float);
  __Pyx_memviewslice (*_scale_xy)(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *, float, float);
  __Pyx_memviewslice (*_shift)(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *, float, float);
  __Pyx_memviewslice (*_rotate)(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *, float, float, float);
  __Pyx_memviewslice (*_polar)(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *, PyObject *);
  __Pyx_memviewslice (*_cartesian)(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *, int, int, PyObject *);
};
static struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_vtabptr_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator;

 035: 
 036:     # autogen_pxd: cdef float[:,:] image
 037:     # autogen_pxd: cdef int w, h
 038:     # autogen_pxd: cdef object original_dtype
 039: 
+040:     def __init__(self, image):
/* Python wrapper */
static int __pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
PyDoc_STRVAR(__pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator___init__, "\n        Interpolate a 2D array\n        :param image: 2D array to interpolate\n        ");
#if CYTHON_UPDATE_DESCRIPTOR_DOC
struct wrapperbase __pyx_wrapperbase_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator___init__;
#endif
static int __pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_image = 0;
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args);
  if (unlikely((__pyx_nargs < 0))) __PYX_ERR(0, 40, __pyx_L3_error)
  #endif
  __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_image,0};
  PyObject* values[1] = {0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  1: values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_VARARGS(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_image)) != 0)) {
          (void)__Pyx_Arg_NewRef_VARARGS(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 40, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "__init__") < 0)) __PYX_ERR(0, 40, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 1)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0);
    }
    __pyx_v_image = values[0];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 40, __pyx_L3_error)
  goto __pyx_L3_error;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_VARARGS(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return -1;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator___init__(((struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self), __pyx_v_image);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_VARARGS(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static int __pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator___init__(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, PyObject *__pyx_v_image) {
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__init__", 0);
  __Pyx_INCREF(__pyx_v_image);
/* … */
  /* function exit code */
  __pyx_r = 0;
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_7);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_8, 1);
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = -1;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_image);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 041:         """
 042:         Interpolate a 2D array
 043:         :param image: 2D array to interpolate
 044:         """
 045: 
+046:         assert image.ndim == 2, "image must be 2D"
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(__pyx_assertions_enabled())) {
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_image, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 46, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_2 = (__Pyx_PyInt_BoolEqObjC(__pyx_t_1, __pyx_int_2, 2, 0)); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 46, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_2)) {
      __Pyx_Raise(__pyx_builtin_AssertionError, __pyx_kp_u_image_must_be_2D, 0, 0);
      __PYX_ERR(0, 46, __pyx_L1_error)
    }
  }
  #else
  if ((1)); else __PYX_ERR(0, 46, __pyx_L1_error)
  #endif
 047: 
+048:         if type(image) is np.ndarray:
  __pyx_t_2 = (((PyObject *)Py_TYPE(__pyx_v_image)) == ((PyObject *)__pyx_ptype_5numpy_ndarray));
  if (__pyx_t_2) {
/* … */
    goto __pyx_L3;
  }
+049:             if not image.flags["C_CONTIGUOUS"]:
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_image, __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 49, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = __Pyx_PyObject_Dict_GetItem(__pyx_t_1, __pyx_n_u_C_CONTIGUOUS); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 49, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 49, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_4 = (!__pyx_t_2);
    if (__pyx_t_4) {
/* … */
    }
+050:                 image = np.ascontiguousarray(image)
      __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 50, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 50, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_1 = NULL;
      __pyx_t_6 = 0;
      #if CYTHON_UNPACK_METHODS
      if (unlikely(PyMethod_Check(__pyx_t_5))) {
        __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
        if (likely(__pyx_t_1)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
          __Pyx_INCREF(__pyx_t_1);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_5, function);
          __pyx_t_6 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_v_image};
        __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
        if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 50, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      }
      __Pyx_DECREF_SET(__pyx_v_image, __pyx_t_3);
      __pyx_t_3 = 0;
+051:             self.image = image.view(np.float32)
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_image, __pyx_n_s_view); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 51, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float32); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 51, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = NULL;
    __pyx_t_6 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_1)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_1);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
        __pyx_t_6 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_7};
      __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 51, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
    __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dsds_float(__pyx_t_3, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 51, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __PYX_XCLEAR_MEMVIEW(&__pyx_v_self->image, 0);
    __pyx_v_self->image = __pyx_t_8;
    __pyx_t_8.memview = NULL;
    __pyx_t_8.data = NULL;
+052:             self.original_dtype = image.dtype
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_image, __pyx_n_s_dtype); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 52, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_GIVEREF(__pyx_t_3);
    __Pyx_GOTREF(__pyx_v_self->original_dtype);
    __Pyx_DECREF(__pyx_v_self->original_dtype);
    __pyx_v_self->original_dtype = __pyx_t_3;
    __pyx_t_3 = 0;
 053:         else: # assume its a memoryview
+054:             self.image = image
  /*else*/ {
    __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dsds_float(__pyx_v_image, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 54, __pyx_L1_error)
    __PYX_XCLEAR_MEMVIEW(&__pyx_v_self->image, 0);
    __pyx_v_self->image = __pyx_t_8;
    __pyx_t_8.memview = NULL;
    __pyx_t_8.data = NULL;
+055:             self.original_dtype = np.float32
    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 55, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 55, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_GIVEREF(__pyx_t_5);
    __Pyx_GOTREF(__pyx_v_self->original_dtype);
    __Pyx_DECREF(__pyx_v_self->original_dtype);
    __pyx_v_self->original_dtype = __pyx_t_5;
    __pyx_t_5 = 0;
  }
  __pyx_L3:;
 056: 
+057:         self.w = image.shape[1]
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_image, __pyx_n_s_shape); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 57, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_5, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 57, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 57, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_self->w = __pyx_t_6;
+058:         self.h = image.shape[0]
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_image, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 58, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 58, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_5); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 58, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_self->h = __pyx_t_6;
 059: 
 060: 
+061:     cdef float _interpolate(self, float x, float y) nogil:
static float __pyx_f_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator__interpolate(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, float __pyx_v_x, float __pyx_v_y) {
  float __pyx_r;
  #ifdef WITH_THREAD
  PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
  #endif
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_interpolate", 0);
  #ifdef WITH_THREAD
  __Pyx_PyGILState_Release(__pyx_gilstate_save);
  #endif
/* … */
  /* function exit code */
  __pyx_L1_error:;
  #ifdef WITH_THREAD
  __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
  #endif
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator._interpolate", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  #ifdef WITH_THREAD
  __Pyx_PyGILState_Release(__pyx_gilstate_save);
  #endif
  __pyx_L0:;
  __Pyx_RefNannyFinishContextNogil()
  return __pyx_r;
}
 062:         """
 063:         Interpolate a 2D array using nearest-neighbor interpolation
 064:         :param x: x position to interpolate
 065:         :param y: y position to interpolate
 066:         :return: interpolated value
 067:         """
+068:         return _interpolate(self.image, x, y)
  if (unlikely(!__pyx_v_self->image.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 68, __pyx_L1_error)}
  __pyx_t_1 = __pyx_f_7nanopyx_4core_9transform_30interpolation_nearest_neighbor__interpolate(__pyx_v_self->image, __pyx_v_x, __pyx_v_y); if (unlikely(__pyx_t_1 == ((double)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 68, __pyx_L1_error)
  __pyx_r = __pyx_t_1;
  goto __pyx_L0;
 069: 
+070:     def magnify(self, int magnification) -> np.ndarray:
/* Python wrapper */
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_3magnify(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_2magnify, "\n        Magnify an image by a factor of magnification\n        :param magnification: magnification factor\n        :return: magnified image\n        ");
static PyMethodDef __pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_3magnify = {"magnify", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_3magnify, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_2magnify};
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_3magnify(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  int __pyx_v_magnification;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyArrayObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("magnify (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args);
  if (unlikely((__pyx_nargs < 0))) __PYX_ERR(0, 70, __pyx_L3_error)
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_magnification,0};
  PyObject* values[1] = {0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_magnification)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 70, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "magnify") < 0)) __PYX_ERR(0, 70, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 1)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
    }
    __pyx_v_magnification = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_magnification == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 70, __pyx_L3_error)
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("magnify", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 70, __pyx_L3_error)
  goto __pyx_L3_error;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.magnify", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_2magnify(((struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self), __pyx_v_magnification);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyArrayObject *__pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_2magnify(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, int __pyx_v_magnification) {
  __Pyx_memviewslice __pyx_v_imMagnified = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyArrayObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("magnify", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_1, 1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.magnify", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_imMagnified, 1);
  __Pyx_XGIVEREF((PyObject *)__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__23 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_magnification, __pyx_n_s_imMagnified); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 70, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__23);
  __Pyx_GIVEREF(__pyx_tuple__23);
/* … */
  __pyx_t_7 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 70, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_return, __pyx_kp_s_np_ndarray) < 0) __PYX_ERR(0, 70, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_3magnify, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Interpolator_magnify, NULL, __pyx_n_s_nanopyx_core_transform_interpola, __pyx_d, ((PyObject *)__pyx_codeobj__24)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_7);
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator, __pyx_n_s_magnify, __pyx_t_4) < 0) __PYX_ERR(0, 70, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  PyType_Modified(__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator);
  __pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_nanopyx_core_transform_inter, __pyx_n_s_magnify, 70, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 70, __pyx_L1_error)
 071:         """
 072:         Magnify an image by a factor of magnification
 073:         :param magnification: magnification factor
 074:         :return: magnified image
 075:         """
+076:         imMagnified = self._magnify(magnification)
  __pyx_t_1 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_magnify(__pyx_v_self, __pyx_v_magnification); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 76, __pyx_L1_error)
  __pyx_v_imMagnified = __pyx_t_1;
  __pyx_t_1.memview = NULL;
  __pyx_t_1.data = NULL;
+077:         return np.asarray(imMagnified).astype(self.original_dtype)
  __Pyx_XDECREF((PyObject *)__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_imMagnified, 2, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_t_4};
    __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 77, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_astype); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_self->original_dtype};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 77, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 77, __pyx_L1_error)
  __pyx_r = ((PyArrayObject *)__pyx_t_2);
  __pyx_t_2 = 0;
  goto __pyx_L0;
 078: 
 079: 
+080:     cdef float[:,:] _magnify(self, float magnification):
static __Pyx_memviewslice __pyx_f_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator__magnify(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, float __pyx_v_magnification) {
  int __pyx_v_i;
  int __pyx_v_j;
  int __pyx_v_wM;
  int __pyx_v_hM;
  float __pyx_v_x;
  float __pyx_v_y;
  __Pyx_memviewslice __pyx_v_imMagnified = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_r = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_magnify", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_6, 1);
  __pyx_r.data = NULL;
  __pyx_r.memview = NULL;
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator._magnify", __pyx_clineno, __pyx_lineno, __pyx_filename);
  goto __pyx_L2;
  __pyx_L0:;
  if (unlikely(!__pyx_r.memview)) {
    PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");
  }
  __pyx_L2:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_imMagnified, 1);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 081:         cdef int i, j
+082:         cdef int wM = int(self.w * magnification)
  __pyx_v_wM = ((int)(__pyx_v_self->w * __pyx_v_magnification));
+083:         cdef int hM = int(self.h * magnification)
  __pyx_v_hM = ((int)(__pyx_v_self->h * __pyx_v_magnification));
 084:         cdef float x, y
 085: 
+086:         cdef float[:,:] imMagnified = np.empty((hM, wM), dtype=np.float32)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_hM); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_wM); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1)) __PYX_ERR(0, 86, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_3);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3)) __PYX_ERR(0, 86, __pyx_L1_error);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4)) __PYX_ERR(0, 86, __pyx_L1_error);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_float(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_imMagnified = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
 087: 
+088:         with nogil:
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      _save = NULL;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L5;
        }
        __pyx_L4_error: {
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L1_error;
        }
        __pyx_L5:;
      }
  }
+089:             for i in prange(wM):
        __pyx_t_7 = __pyx_v_wM;
        {
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   (x)
                #define unlikely(x) (x)
            #endif
            __pyx_t_9 = (__pyx_t_7 - 0 + 1 - 1/abs(1)) / 1;
            if (__pyx_t_9 > 0)
            {
                #ifdef _OPENMP
                #pragma omp parallel
                #endif /* _OPENMP */
                {
                    #ifdef _OPENMP
                    #pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_j) lastprivate(__pyx_v_x) lastprivate(__pyx_v_y)
                    #endif /* _OPENMP */
                    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_9; __pyx_t_8++){
                        {
                            __pyx_v_i = (int)(0 + 1 * __pyx_t_8);
                            /* Initialize private variables to invalid values */
                            __pyx_v_j = ((int)0xbad0bad0);
                            __pyx_v_x = ((float)__PYX_NAN());
                            __pyx_v_y = ((float)__PYX_NAN());
+090:                 x = i / magnification
                            __pyx_v_x = (((float)__pyx_v_i) / __pyx_v_magnification);
+091:                 for j in range(hM):
                            __pyx_t_10 = __pyx_v_hM;
                            __pyx_t_11 = __pyx_t_10;
                            for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
                              __pyx_v_j = __pyx_t_12;
+092:                     y = j / magnification
                              __pyx_v_y = (((float)__pyx_v_j) / __pyx_v_magnification);
+093:                     imMagnified[j, i] = self._interpolate(x, y)
                              __pyx_t_13 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_interpolate(__pyx_v_self, __pyx_v_x, __pyx_v_y); if (unlikely(__Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 93, __pyx_L8_error)
                              __pyx_t_14 = __pyx_v_j;
                              __pyx_t_15 = __pyx_v_i;
                              *((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_imMagnified.data + __pyx_t_14 * __pyx_v_imMagnified.strides[0]) ) + __pyx_t_15 * __pyx_v_imMagnified.strides[1]) )) = __pyx_t_13;
                            }
                            goto __pyx_L13;
                            __pyx_L8_error:;
                            {
                                #ifdef WITH_THREAD
                                PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                                #endif
                                #ifdef _OPENMP
                                #pragma omp flush(__pyx_parallel_exc_type)
                                #endif /* _OPENMP */
                                if (!__pyx_parallel_exc_type) {
                                  __Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb);
                                  __pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno;
                                  __Pyx_GOTREF(__pyx_parallel_exc_type);
                                }
                                #ifdef WITH_THREAD
                                __Pyx_PyGILState_Release(__pyx_gilstate_save);
                                #endif
                            }
                            __pyx_parallel_why = 4;
                            goto __pyx_L12;
                            __pyx_L12:;
                            #ifdef _OPENMP
                            #pragma omp critical(__pyx_parallel_lastprivates8)
                            #endif /* _OPENMP */
                            {
                                __pyx_parallel_temp0 = __pyx_v_i;
                                __pyx_parallel_temp1 = __pyx_v_j;
                                __pyx_parallel_temp2 = __pyx_v_x;
                                __pyx_parallel_temp3 = __pyx_v_y;
                            }
                            __pyx_L13:;
                            #ifdef _OPENMP
                            #pragma omp flush(__pyx_parallel_why)
                            #endif /* _OPENMP */
                        }
                    }
                    #ifdef _OPENMP
                    Py_END_ALLOW_THREADS
                    #else
{
#ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    #endif /* _OPENMP */
                    /* Clean up any temporaries */
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                    #ifndef _OPENMP
}
#endif /* _OPENMP */
                }
            }
            if (__pyx_parallel_exc_type) {
              /* This may have been overridden by a continue, break or return in another thread. Prefer the error. */
              __pyx_parallel_why = 4;
            }
            if (__pyx_parallel_why) {
              __pyx_v_i = __pyx_parallel_temp0;
              __pyx_v_j = __pyx_parallel_temp1;
              __pyx_v_x = __pyx_parallel_temp2;
              __pyx_v_y = __pyx_parallel_temp3;
              switch (__pyx_parallel_why) {
                    case 4:
                {
                    #ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    __Pyx_GIVEREF(__pyx_parallel_exc_type);
                    __Pyx_ErrRestoreWithState(__pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb);
                    __pyx_filename = __pyx_parallel_filename; __pyx_lineno = __pyx_parallel_lineno; __pyx_clineno = __pyx_parallel_clineno;
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                }
                goto __pyx_L4_error;
              }
            }
        }
        #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
            #undef likely
            #undef unlikely
            #define likely(x)   __builtin_expect(!!(x), 1)
            #define unlikely(x) __builtin_expect(!!(x), 0)
        #endif
      }
 094: 
+095:         return imMagnified
  __PYX_INC_MEMVIEW(&__pyx_v_imMagnified, 1);
  __pyx_r = __pyx_v_imMagnified;
  goto __pyx_L0;
 096: 
+097:     def magnify_xy(self, int magnification_y, int magnification_x) -> np.ndarray:
/* Python wrapper */
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_5magnify_xy(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_4magnify_xy, "\n        Magnify an image by a factor of magnification\n        :param magnification: magnification factor\n        :return: magnified image\n        ");
static PyMethodDef __pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_5magnify_xy = {"magnify_xy", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_5magnify_xy, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_4magnify_xy};
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_5magnify_xy(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  int __pyx_v_magnification_y;
  int __pyx_v_magnification_x;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyArrayObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("magnify_xy (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args);
  if (unlikely((__pyx_nargs < 0))) __PYX_ERR(0, 97, __pyx_L3_error)
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_magnification_y,&__pyx_n_s_magnification_x,0};
  PyObject* values[2] = {0,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_magnification_y)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_magnification_x)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("magnify_xy", 1, 2, 2, 1); __PYX_ERR(0, 97, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "magnify_xy") < 0)) __PYX_ERR(0, 97, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_magnification_y = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_magnification_y == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L3_error)
    __pyx_v_magnification_x = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_magnification_x == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L3_error)
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("magnify_xy", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 97, __pyx_L3_error)
  goto __pyx_L3_error;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.magnify_xy", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_4magnify_xy(((struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self), __pyx_v_magnification_y, __pyx_v_magnification_x);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyArrayObject *__pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_4magnify_xy(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, int __pyx_v_magnification_y, int __pyx_v_magnification_x) {
  __Pyx_memviewslice __pyx_v_imMagnified = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyArrayObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("magnify_xy", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_1, 1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.magnify_xy", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_imMagnified, 1);
  __Pyx_XGIVEREF((PyObject *)__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__25 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_magnification_y, __pyx_n_s_magnification_x, __pyx_n_s_imMagnified); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 97, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__25);
  __Pyx_GIVEREF(__pyx_tuple__25);
/* … */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 97, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_kp_s_np_ndarray) < 0) __PYX_ERR(0, 97, __pyx_L1_error)
  __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_5magnify_xy, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Interpolator_magnify_xy, NULL, __pyx_n_s_nanopyx_core_transform_interpola, __pyx_d, ((PyObject *)__pyx_codeobj__26)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 97, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_7, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator, __pyx_n_s_magnify_xy, __pyx_t_7) < 0) __PYX_ERR(0, 97, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  PyType_Modified(__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator);
  __pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_nanopyx_core_transform_inter, __pyx_n_s_magnify_xy, 97, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) __PYX_ERR(0, 97, __pyx_L1_error)
 098:         """
 099:         Magnify an image by a factor of magnification
 100:         :param magnification: magnification factor
 101:         :return: magnified image
 102:         """
+103:         imMagnified = self._magnify_xy(magnification_y, magnification_x)
  __pyx_t_1 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_magnify_xy(__pyx_v_self, __pyx_v_magnification_y, __pyx_v_magnification_x); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 103, __pyx_L1_error)
  __pyx_v_imMagnified = __pyx_t_1;
  __pyx_t_1.memview = NULL;
  __pyx_t_1.data = NULL;
+104:         return np.asarray(imMagnified).astype(self.original_dtype)
  __Pyx_XDECREF((PyObject *)__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 104, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 104, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_imMagnified, 2, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 104, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_t_4};
    __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_astype); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 104, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_self->original_dtype};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 104, __pyx_L1_error)
  __pyx_r = ((PyArrayObject *)__pyx_t_2);
  __pyx_t_2 = 0;
  goto __pyx_L0;
 105: 
+106:     cdef float[:,:] _magnify_xy(self, float magnification_y, float magnification_x):
static __Pyx_memviewslice __pyx_f_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator__magnify_xy(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, float __pyx_v_magnification_y, float __pyx_v_magnification_x) {
  int __pyx_v_i;
  int __pyx_v_j;
  int __pyx_v_wM;
  int __pyx_v_hM;
  float __pyx_v_x;
  float __pyx_v_y;
  __Pyx_memviewslice __pyx_v_imMagnified = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_r = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_magnify_xy", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_6, 1);
  __pyx_r.data = NULL;
  __pyx_r.memview = NULL;
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator._magnify_xy", __pyx_clineno, __pyx_lineno, __pyx_filename);
  goto __pyx_L2;
  __pyx_L0:;
  if (unlikely(!__pyx_r.memview)) {
    PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");
  }
  __pyx_L2:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_imMagnified, 1);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 107:         cdef int i, j
+108:         cdef int wM = int(self.w * magnification_x)
  __pyx_v_wM = ((int)(__pyx_v_self->w * __pyx_v_magnification_x));
+109:         cdef int hM = int(self.h * magnification_y)
  __pyx_v_hM = ((int)(__pyx_v_self->h * __pyx_v_magnification_y));
 110:         cdef float x, y
 111: 
+112:         cdef float[:,:] imMagnified = np.empty((hM, wM), dtype=np.float32)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_hM); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_wM); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1)) __PYX_ERR(0, 112, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_3);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3)) __PYX_ERR(0, 112, __pyx_L1_error);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4)) __PYX_ERR(0, 112, __pyx_L1_error);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_float(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_imMagnified = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
 113: 
+114:         with nogil:
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      _save = NULL;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L5;
        }
        __pyx_L4_error: {
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L1_error;
        }
        __pyx_L5:;
      }
  }
+115:             for i in prange(wM):
        __pyx_t_7 = __pyx_v_wM;
        {
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   (x)
                #define unlikely(x) (x)
            #endif
            __pyx_t_9 = (__pyx_t_7 - 0 + 1 - 1/abs(1)) / 1;
            if (__pyx_t_9 > 0)
            {
                #ifdef _OPENMP
                #pragma omp parallel
                #endif /* _OPENMP */
                {
                    #ifdef _OPENMP
                    #pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_j) lastprivate(__pyx_v_x) lastprivate(__pyx_v_y)
                    #endif /* _OPENMP */
                    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_9; __pyx_t_8++){
                        {
                            __pyx_v_i = (int)(0 + 1 * __pyx_t_8);
                            /* Initialize private variables to invalid values */
                            __pyx_v_j = ((int)0xbad0bad0);
                            __pyx_v_x = ((float)__PYX_NAN());
                            __pyx_v_y = ((float)__PYX_NAN());
+116:                 x = i / magnification_x
                            __pyx_v_x = (((float)__pyx_v_i) / __pyx_v_magnification_x);
+117:                 for j in range(hM):
                            __pyx_t_10 = __pyx_v_hM;
                            __pyx_t_11 = __pyx_t_10;
                            for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
                              __pyx_v_j = __pyx_t_12;
+118:                     y = j / magnification_y
                              __pyx_v_y = (((float)__pyx_v_j) / __pyx_v_magnification_y);
+119:                     imMagnified[j, i] = self._interpolate(x, y)
                              __pyx_t_13 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_interpolate(__pyx_v_self, __pyx_v_x, __pyx_v_y); if (unlikely(__Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 119, __pyx_L8_error)
                              __pyx_t_14 = __pyx_v_j;
                              __pyx_t_15 = __pyx_v_i;
                              *((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_imMagnified.data + __pyx_t_14 * __pyx_v_imMagnified.strides[0]) ) + __pyx_t_15 * __pyx_v_imMagnified.strides[1]) )) = __pyx_t_13;
                            }
                            goto __pyx_L13;
                            __pyx_L8_error:;
                            {
                                #ifdef WITH_THREAD
                                PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                                #endif
                                #ifdef _OPENMP
                                #pragma omp flush(__pyx_parallel_exc_type)
                                #endif /* _OPENMP */
                                if (!__pyx_parallel_exc_type) {
                                  __Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb);
                                  __pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno;
                                  __Pyx_GOTREF(__pyx_parallel_exc_type);
                                }
                                #ifdef WITH_THREAD
                                __Pyx_PyGILState_Release(__pyx_gilstate_save);
                                #endif
                            }
                            __pyx_parallel_why = 4;
                            goto __pyx_L12;
                            __pyx_L12:;
                            #ifdef _OPENMP
                            #pragma omp critical(__pyx_parallel_lastprivates9)
                            #endif /* _OPENMP */
                            {
                                __pyx_parallel_temp0 = __pyx_v_i;
                                __pyx_parallel_temp1 = __pyx_v_j;
                                __pyx_parallel_temp2 = __pyx_v_x;
                                __pyx_parallel_temp3 = __pyx_v_y;
                            }
                            __pyx_L13:;
                            #ifdef _OPENMP
                            #pragma omp flush(__pyx_parallel_why)
                            #endif /* _OPENMP */
                        }
                    }
                    #ifdef _OPENMP
                    Py_END_ALLOW_THREADS
                    #else
{
#ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    #endif /* _OPENMP */
                    /* Clean up any temporaries */
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                    #ifndef _OPENMP
}
#endif /* _OPENMP */
                }
            }
            if (__pyx_parallel_exc_type) {
              /* This may have been overridden by a continue, break or return in another thread. Prefer the error. */
              __pyx_parallel_why = 4;
            }
            if (__pyx_parallel_why) {
              __pyx_v_i = __pyx_parallel_temp0;
              __pyx_v_j = __pyx_parallel_temp1;
              __pyx_v_x = __pyx_parallel_temp2;
              __pyx_v_y = __pyx_parallel_temp3;
              switch (__pyx_parallel_why) {
                    case 4:
                {
                    #ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    __Pyx_GIVEREF(__pyx_parallel_exc_type);
                    __Pyx_ErrRestoreWithState(__pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb);
                    __pyx_filename = __pyx_parallel_filename; __pyx_lineno = __pyx_parallel_lineno; __pyx_clineno = __pyx_parallel_clineno;
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                }
                goto __pyx_L4_error;
              }
            }
        }
        #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
            #undef likely
            #undef unlikely
            #define likely(x)   __builtin_expect(!!(x), 1)
            #define unlikely(x) __builtin_expect(!!(x), 0)
        #endif
      }
 120: 
+121:         return imMagnified
  __PYX_INC_MEMVIEW(&__pyx_v_imMagnified, 1);
  __pyx_r = __pyx_v_imMagnified;
  goto __pyx_L0;
 122: 
+123:     def scale_xy(self, float scaling_y, float scaling_x) -> np.ndarray:
/* Python wrapper */
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_7scale_xy(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_6scale_xy, "\n        Scale an image by a factor.\n        Equivalent to magnify_xy but takes floats as inputs and mantains image shape.\n        :param scaling_y: scale factor in y\n        :param scaling_x: scale factor in x\n        :return: scaled image\n        ");
static PyMethodDef __pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_7scale_xy = {"scale_xy", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_7scale_xy, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_6scale_xy};
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_7scale_xy(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  float __pyx_v_scaling_y;
  float __pyx_v_scaling_x;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyArrayObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("scale_xy (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args);
  if (unlikely((__pyx_nargs < 0))) __PYX_ERR(0, 123, __pyx_L3_error)
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scaling_y,&__pyx_n_s_scaling_x,0};
  PyObject* values[2] = {0,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_scaling_y)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 123, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_scaling_x)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 123, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("scale_xy", 1, 2, 2, 1); __PYX_ERR(0, 123, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "scale_xy") < 0)) __PYX_ERR(0, 123, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_scaling_y = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_scaling_y == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 123, __pyx_L3_error)
    __pyx_v_scaling_x = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_scaling_x == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 123, __pyx_L3_error)
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("scale_xy", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 123, __pyx_L3_error)
  goto __pyx_L3_error;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.scale_xy", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_6scale_xy(((struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self), __pyx_v_scaling_y, __pyx_v_scaling_x);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyArrayObject *__pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_6scale_xy(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, float __pyx_v_scaling_y, float __pyx_v_scaling_x) {
  __Pyx_memviewslice __pyx_v_imScaled = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyArrayObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("scale_xy", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_1, 1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.scale_xy", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_imScaled, 1);
  __Pyx_XGIVEREF((PyObject *)__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__27 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_scaling_y, __pyx_n_s_scaling_x, __pyx_n_s_imScaled); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__27);
  __Pyx_GIVEREF(__pyx_tuple__27);
/* … */
  __pyx_t_7 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_return, __pyx_kp_s_np_ndarray) < 0) __PYX_ERR(0, 123, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_7scale_xy, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Interpolator_scale_xy, NULL, __pyx_n_s_nanopyx_core_transform_interpola, __pyx_d, ((PyObject *)__pyx_codeobj__28)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_7);
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator, __pyx_n_s_scale_xy, __pyx_t_4) < 0) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  PyType_Modified(__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator);
  __pyx_codeobj__28 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__27, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_nanopyx_core_transform_inter, __pyx_n_s_scale_xy, 123, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__28)) __PYX_ERR(0, 123, __pyx_L1_error)
 124:         """
 125:         Scale an image by a factor.
 126:         Equivalent to magnify_xy but takes floats as inputs and mantains image shape.
 127:         :param scaling_y: scale factor in y
 128:         :param scaling_x: scale factor in x
 129:         :return: scaled image
 130:         """
+131:         imScaled = self._scale_xy(scaling_y, scaling_x)
  __pyx_t_1 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_scale_xy(__pyx_v_self, __pyx_v_scaling_y, __pyx_v_scaling_x); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 131, __pyx_L1_error)
  __pyx_v_imScaled = __pyx_t_1;
  __pyx_t_1.memview = NULL;
  __pyx_t_1.data = NULL;
+132:         return np.asarray(imScaled).astype(self.original_dtype)
  __Pyx_XDECREF((PyObject *)__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 132, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 132, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_imScaled, 2, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 132, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_t_4};
    __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 132, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_astype); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 132, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_self->original_dtype};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 132, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 132, __pyx_L1_error)
  __pyx_r = ((PyArrayObject *)__pyx_t_2);
  __pyx_t_2 = 0;
  goto __pyx_L0;
 133: 
+134:     cdef float[:,:] _scale_xy(self, float scaling_y, float scaling_x):
static __Pyx_memviewslice __pyx_f_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator__scale_xy(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, float __pyx_v_scaling_y, float __pyx_v_scaling_x) {
  int __pyx_v_i;
  int __pyx_v_j;
  float __pyx_v_x;
  float __pyx_v_y;
  float __pyx_v_wM;
  float __pyx_v_hM;
  __Pyx_memviewslice __pyx_v_imScaled = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_r = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_scale_xy", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_6, 1);
  __pyx_r.data = NULL;
  __pyx_r.memview = NULL;
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator._scale_xy", __pyx_clineno, __pyx_lineno, __pyx_filename);
  goto __pyx_L2;
  __pyx_L0:;
  if (unlikely(!__pyx_r.memview)) {
    PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");
  }
  __pyx_L2:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_imScaled, 1);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 135:         cdef int i, j
 136:         cdef float x, y
+137:         cdef float wM = self.w * scaling_x
  __pyx_v_wM = (__pyx_v_self->w * __pyx_v_scaling_x);
+138:         cdef float hM = self.h * scaling_y
  __pyx_v_hM = (__pyx_v_self->h * __pyx_v_scaling_y);
+139:         cdef float[:,:] imScaled = np.empty((self.h, self.w), dtype=np.float32)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->h); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_self->w); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1)) __PYX_ERR(0, 139, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_3);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3)) __PYX_ERR(0, 139, __pyx_L1_error);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4)) __PYX_ERR(0, 139, __pyx_L1_error);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_float(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 139, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_imScaled = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
 140: 
+141:         with nogil:
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      _save = NULL;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L5;
        }
        __pyx_L4_error: {
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L1_error;
        }
        __pyx_L5:;
      }
  }
+142:             for i in prange(self.w):
        __pyx_t_7 = __pyx_v_self->w;
        {
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   (x)
                #define unlikely(x) (x)
            #endif
            __pyx_t_9 = (__pyx_t_7 - 0 + 1 - 1/abs(1)) / 1;
            if (__pyx_t_9 > 0)
            {
                #ifdef _OPENMP
                #pragma omp parallel
                #endif /* _OPENMP */
                {
                    #ifdef _OPENMP
                    #pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_j) lastprivate(__pyx_v_x) lastprivate(__pyx_v_y)
                    #endif /* _OPENMP */
                    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_9; __pyx_t_8++){
                        {
                            __pyx_v_i = (int)(0 + 1 * __pyx_t_8);
                            /* Initialize private variables to invalid values */
                            __pyx_v_j = ((int)0xbad0bad0);
                            __pyx_v_x = ((float)__PYX_NAN());
                            __pyx_v_y = ((float)__PYX_NAN());
+143:                 x = (i+(wM/2-self.w/2)) / scaling_x
                            __pyx_v_x = ((__pyx_v_i + ((__pyx_v_wM / 2.0) - (((long)__pyx_v_self->w) / 2))) / __pyx_v_scaling_x);
+144:                 for j in range(self.h):
                            __pyx_t_10 = __pyx_v_self->h;
                            __pyx_t_11 = __pyx_t_10;
                            for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
                              __pyx_v_j = __pyx_t_12;
+145:                     y = (j+(hM/2-self.h/2)) / scaling_y
                              __pyx_v_y = ((__pyx_v_j + ((__pyx_v_hM / 2.0) - (((long)__pyx_v_self->h) / 2))) / __pyx_v_scaling_y);
+146:                     imScaled[j, i] = self._interpolate(x, y)
                              __pyx_t_13 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_interpolate(__pyx_v_self, __pyx_v_x, __pyx_v_y); if (unlikely(__Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 146, __pyx_L8_error)
                              __pyx_t_14 = __pyx_v_j;
                              __pyx_t_15 = __pyx_v_i;
                              *((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_imScaled.data + __pyx_t_14 * __pyx_v_imScaled.strides[0]) ) + __pyx_t_15 * __pyx_v_imScaled.strides[1]) )) = __pyx_t_13;
                            }
                            goto __pyx_L13;
                            __pyx_L8_error:;
                            {
                                #ifdef WITH_THREAD
                                PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                                #endif
                                #ifdef _OPENMP
                                #pragma omp flush(__pyx_parallel_exc_type)
                                #endif /* _OPENMP */
                                if (!__pyx_parallel_exc_type) {
                                  __Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb);
                                  __pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno;
                                  __Pyx_GOTREF(__pyx_parallel_exc_type);
                                }
                                #ifdef WITH_THREAD
                                __Pyx_PyGILState_Release(__pyx_gilstate_save);
                                #endif
                            }
                            __pyx_parallel_why = 4;
                            goto __pyx_L12;
                            __pyx_L12:;
                            #ifdef _OPENMP
                            #pragma omp critical(__pyx_parallel_lastprivates10)
                            #endif /* _OPENMP */
                            {
                                __pyx_parallel_temp0 = __pyx_v_i;
                                __pyx_parallel_temp1 = __pyx_v_j;
                                __pyx_parallel_temp2 = __pyx_v_x;
                                __pyx_parallel_temp3 = __pyx_v_y;
                            }
                            __pyx_L13:;
                            #ifdef _OPENMP
                            #pragma omp flush(__pyx_parallel_why)
                            #endif /* _OPENMP */
                        }
                    }
                    #ifdef _OPENMP
                    Py_END_ALLOW_THREADS
                    #else
{
#ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    #endif /* _OPENMP */
                    /* Clean up any temporaries */
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                    #ifndef _OPENMP
}
#endif /* _OPENMP */
                }
            }
            if (__pyx_parallel_exc_type) {
              /* This may have been overridden by a continue, break or return in another thread. Prefer the error. */
              __pyx_parallel_why = 4;
            }
            if (__pyx_parallel_why) {
              __pyx_v_i = __pyx_parallel_temp0;
              __pyx_v_j = __pyx_parallel_temp1;
              __pyx_v_x = __pyx_parallel_temp2;
              __pyx_v_y = __pyx_parallel_temp3;
              switch (__pyx_parallel_why) {
                    case 4:
                {
                    #ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    __Pyx_GIVEREF(__pyx_parallel_exc_type);
                    __Pyx_ErrRestoreWithState(__pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb);
                    __pyx_filename = __pyx_parallel_filename; __pyx_lineno = __pyx_parallel_lineno; __pyx_clineno = __pyx_parallel_clineno;
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                }
                goto __pyx_L4_error;
              }
            }
        }
        #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
            #undef likely
            #undef unlikely
            #define likely(x)   __builtin_expect(!!(x), 1)
            #define unlikely(x) __builtin_expect(!!(x), 0)
        #endif
      }
 147: 
+148:         return imScaled
  __PYX_INC_MEMVIEW(&__pyx_v_imScaled, 1);
  __pyx_r = __pyx_v_imScaled;
  goto __pyx_L0;
 149: 
+150:     def shift(self, double dx, double dy) -> np.ndarray:
/* Python wrapper */
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_9shift(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_8shift, "\n        Shift an image by (dx, dy) using interpolation\n        :param dx: shift along x-axis\n        :param dy: shift along y-axis\n        :return: shifted image\n        ");
static PyMethodDef __pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_9shift = {"shift", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_9shift, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_8shift};
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_9shift(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  double __pyx_v_dx;
  double __pyx_v_dy;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyArrayObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("shift (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args);
  if (unlikely((__pyx_nargs < 0))) __PYX_ERR(0, 150, __pyx_L3_error)
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_dx,&__pyx_n_s_dy,0};
  PyObject* values[2] = {0,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_dx)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 150, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_dy)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 150, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("shift", 1, 2, 2, 1); __PYX_ERR(0, 150, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "shift") < 0)) __PYX_ERR(0, 150, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_dx = __pyx_PyFloat_AsDouble(values[0]); if (unlikely((__pyx_v_dx == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 150, __pyx_L3_error)
    __pyx_v_dy = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_dy == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 150, __pyx_L3_error)
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("shift", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 150, __pyx_L3_error)
  goto __pyx_L3_error;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.shift", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_8shift(((struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self), __pyx_v_dx, __pyx_v_dy);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyArrayObject *__pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_8shift(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, double __pyx_v_dx, double __pyx_v_dy) {
  __Pyx_memviewslice __pyx_v_imShifted = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyArrayObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("shift", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_1, 1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.shift", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_imShifted, 1);
  __Pyx_XGIVEREF((PyObject *)__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__29 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_dx, __pyx_n_s_dy, __pyx_n_s_imShifted); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(0, 150, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__29);
  __Pyx_GIVEREF(__pyx_tuple__29);
/* … */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 150, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_kp_s_np_ndarray) < 0) __PYX_ERR(0, 150, __pyx_L1_error)
  __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_9shift, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Interpolator_shift, NULL, __pyx_n_s_nanopyx_core_transform_interpola, __pyx_d, ((PyObject *)__pyx_codeobj__30)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 150, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_7, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator, __pyx_n_s_shift, __pyx_t_7) < 0) __PYX_ERR(0, 150, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  PyType_Modified(__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator);
  __pyx_codeobj__30 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__29, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_nanopyx_core_transform_inter, __pyx_n_s_shift, 150, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__30)) __PYX_ERR(0, 150, __pyx_L1_error)
 151:         """
 152:         Shift an image by (dx, dy) using interpolation
 153:         :param dx: shift along x-axis
 154:         :param dy: shift along y-axis
 155:         :return: shifted image
 156:         """
+157:         imShifted = self._shift(dx, dy)
  __pyx_t_1 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_shift(__pyx_v_self, __pyx_v_dx, __pyx_v_dy); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 157, __pyx_L1_error)
  __pyx_v_imShifted = __pyx_t_1;
  __pyx_t_1.memview = NULL;
  __pyx_t_1.data = NULL;
+158:         return np.asarray(imShifted).astype(self.original_dtype)
  __Pyx_XDECREF((PyObject *)__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 158, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 158, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_imShifted, 2, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 158, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_t_4};
    __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 158, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_astype); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 158, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_self->original_dtype};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 158, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 158, __pyx_L1_error)
  __pyx_r = ((PyArrayObject *)__pyx_t_2);
  __pyx_t_2 = 0;
  goto __pyx_L0;
 159: 
 160: 
+161:     cdef float[:,:] _shift(self, float dx, float dy):
static __Pyx_memviewslice __pyx_f_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator__shift(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, float __pyx_v_dx, float __pyx_v_dy) {
  __Pyx_memviewslice __pyx_v_imShifted = { 0, 0, { 0 }, { 0 }, { 0 } };
  int __pyx_v_i;
  int __pyx_v_j;
  int __pyx_v__dx;
  int __pyx_v__dy;
  CYTHON_UNUSED int __pyx_v_x_start;
  int __pyx_v_y_start;
  CYTHON_UNUSED int __pyx_v_x_end;
  int __pyx_v_y_end;
  __Pyx_memviewslice __pyx_r = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_shift", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_6, 1);
  __pyx_r.data = NULL;
  __pyx_r.memview = NULL;
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator._shift", __pyx_clineno, __pyx_lineno, __pyx_filename);
  goto __pyx_L2;
  __pyx_L0:;
  if (unlikely(!__pyx_r.memview)) {
    PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");
  }
  __pyx_L2:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_imShifted, 1);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 162: 
+163:         cdef float[:,:] imShifted = np.zeros((self.h, self.w), dtype=np.float32)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->h); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_self->w); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1)) __PYX_ERR(0, 163, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_3);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3)) __PYX_ERR(0, 163, __pyx_L1_error);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4)) __PYX_ERR(0, 163, __pyx_L1_error);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_float(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 163, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_imShifted = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
 164: 
 165:         cdef int i, j
+166:         cdef int _dx = int(dx)
  __pyx_v__dx = ((int)__pyx_v_dx);
+167:         cdef int _dy = int(dy)
  __pyx_v__dy = ((int)__pyx_v_dy);
+168:         cdef int x_start = max(0, _dx)
  __pyx_t_7 = __pyx_v__dx;
  __pyx_t_8 = 0;
  __pyx_t_10 = (__pyx_t_7 > __pyx_t_8);
  if (__pyx_t_10) {
    __pyx_t_9 = __pyx_t_7;
  } else {
    __pyx_t_9 = __pyx_t_8;
  }
  __pyx_v_x_start = __pyx_t_9;
+169:         cdef int y_start = max(0, _dy)
  __pyx_t_7 = __pyx_v__dy;
  __pyx_t_9 = 0;
  __pyx_t_10 = (__pyx_t_7 > __pyx_t_9);
  if (__pyx_t_10) {
    __pyx_t_8 = __pyx_t_7;
  } else {
    __pyx_t_8 = __pyx_t_9;
  }
  __pyx_v_y_start = __pyx_t_8;
+170:         cdef int x_end = min(self.w, self.w + _dx)
  __pyx_t_7 = (__pyx_v_self->w + __pyx_v__dx);
  __pyx_t_11 = __pyx_v_self->w;
  __pyx_t_10 = (__pyx_t_7 < __pyx_t_11);
  if (__pyx_t_10) {
    __pyx_t_12 = __pyx_t_7;
  } else {
    __pyx_t_12 = __pyx_t_11;
  }
  __pyx_v_x_end = __pyx_t_12;
+171:         cdef int y_end = min(self.h, self.h + _dy)
  __pyx_t_12 = (__pyx_v_self->h + __pyx_v__dy);
  __pyx_t_7 = __pyx_v_self->h;
  __pyx_t_10 = (__pyx_t_12 < __pyx_t_7);
  if (__pyx_t_10) {
    __pyx_t_11 = __pyx_t_12;
  } else {
    __pyx_t_11 = __pyx_t_7;
  }
  __pyx_v_y_end = __pyx_t_11;
 172: 
+173:         with nogil:
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      _save = NULL;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L5;
        }
        __pyx_L4_error: {
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L1_error;
        }
        __pyx_L5:;
      }
  }
+174:             for i in prange(x_start, x_end):
        __pyx_t_11 = __pyx_v_x_start;
        __pyx_t_12 = __pyx_v_x_end;
        {
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   (x)
                #define unlikely(x) (x)
            #endif
            __pyx_t_13 = (__pyx_t_12 - __pyx_t_11 + 1 - 1/abs(1)) / 1;
            if (__pyx_t_13 > 0)
            {
                #ifdef _OPENMP
                #pragma omp parallel
                #endif /* _OPENMP */
                {
                    #ifdef _OPENMP
                    #pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_j)
                    #endif /* _OPENMP */
                    for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_13; __pyx_t_7++){
                        {
                            __pyx_v_i = (int)(__pyx_t_11 + 1 * __pyx_t_7);
                            /* Initialize private variables to invalid values */
                            __pyx_v_j = ((int)0xbad0bad0);
+175:                 for j in range(y_start, y_end):
                            __pyx_t_14 = __pyx_v_y_end;
                            __pyx_t_15 = __pyx_t_14;
                            for (__pyx_t_16 = __pyx_v_y_start; __pyx_t_16 < __pyx_t_15; __pyx_t_16+=1) {
                              __pyx_v_j = __pyx_t_16;
+176:                     imShifted[j,i] = self._interpolate(i - dx, j - dy)
                              __pyx_t_17 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_interpolate(__pyx_v_self, (__pyx_v_i - __pyx_v_dx), (__pyx_v_j - __pyx_v_dy)); if (unlikely(__Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 176, __pyx_L8_error)
                              __pyx_t_18 = __pyx_v_j;
                              __pyx_t_19 = __pyx_v_i;
                              *((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_imShifted.data + __pyx_t_18 * __pyx_v_imShifted.strides[0]) ) + __pyx_t_19 * __pyx_v_imShifted.strides[1]) )) = __pyx_t_17;
                            }
                            goto __pyx_L13;
                            __pyx_L8_error:;
                            {
                                #ifdef WITH_THREAD
                                PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                                #endif
                                #ifdef _OPENMP
                                #pragma omp flush(__pyx_parallel_exc_type)
                                #endif /* _OPENMP */
                                if (!__pyx_parallel_exc_type) {
                                  __Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb);
                                  __pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno;
                                  __Pyx_GOTREF(__pyx_parallel_exc_type);
                                }
                                #ifdef WITH_THREAD
                                __Pyx_PyGILState_Release(__pyx_gilstate_save);
                                #endif
                            }
                            __pyx_parallel_why = 4;
                            goto __pyx_L12;
                            __pyx_L12:;
                            #ifdef _OPENMP
                            #pragma omp critical(__pyx_parallel_lastprivates11)
                            #endif /* _OPENMP */
                            {
                                __pyx_parallel_temp0 = __pyx_v_i;
                                __pyx_parallel_temp1 = __pyx_v_j;
                            }
                            __pyx_L13:;
                            #ifdef _OPENMP
                            #pragma omp flush(__pyx_parallel_why)
                            #endif /* _OPENMP */
                        }
                    }
                    #ifdef _OPENMP
                    Py_END_ALLOW_THREADS
                    #else
{
#ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    #endif /* _OPENMP */
                    /* Clean up any temporaries */
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                    #ifndef _OPENMP
}
#endif /* _OPENMP */
                }
            }
            if (__pyx_parallel_exc_type) {
              /* This may have been overridden by a continue, break or return in another thread. Prefer the error. */
              __pyx_parallel_why = 4;
            }
            if (__pyx_parallel_why) {
              __pyx_v_i = __pyx_parallel_temp0;
              __pyx_v_j = __pyx_parallel_temp1;
              switch (__pyx_parallel_why) {
                    case 4:
                {
                    #ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    __Pyx_GIVEREF(__pyx_parallel_exc_type);
                    __Pyx_ErrRestoreWithState(__pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb);
                    __pyx_filename = __pyx_parallel_filename; __pyx_lineno = __pyx_parallel_lineno; __pyx_clineno = __pyx_parallel_clineno;
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                }
                goto __pyx_L4_error;
              }
            }
        }
        #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
            #undef likely
            #undef unlikely
            #define likely(x)   __builtin_expect(!!(x), 1)
            #define unlikely(x) __builtin_expect(!!(x), 0)
        #endif
      }
 177: 
+178:         return imShifted
  __PYX_INC_MEMVIEW(&__pyx_v_imShifted, 1);
  __pyx_r = __pyx_v_imShifted;
  goto __pyx_L0;
 179: 
 180: 
+181:     def rotate(self, float angle, float cx=-1, float cy=-1) -> np.ndarray:
/* Python wrapper */
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_11rotate(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_10rotate, "\n        Rotate an image by angle radians around (cx,cy) using interpolation\n        :param angle: rotation angle in radians, positive angles are counter clockwise\n        :param cx: x coordinate of the center of rotation, defaults to image center if negative\n        :param cy: y coordinate of the center of rotation, defaults to image center if negative\n        ");
static PyMethodDef __pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_11rotate = {"rotate", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_11rotate, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_10rotate};
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_11rotate(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  float __pyx_v_angle;
  float __pyx_v_cx;
  float __pyx_v_cy;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyArrayObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("rotate (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args);
  if (unlikely((__pyx_nargs < 0))) __PYX_ERR(0, 181, __pyx_L3_error)
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_angle,&__pyx_n_s_cx,&__pyx_n_s_cy,0};
  PyObject* values[3] = {0,0,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_angle)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (kw_args > 0) {
          PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_cx);
          if (value) { values[1] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; }
          else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_cy);
          if (value) { values[2] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; }
          else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "rotate") < 0)) __PYX_ERR(0, 181, __pyx_L3_error)
      }
    } else {
      switch (__pyx_nargs) {
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_angle = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_angle == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L3_error)
    if (values[1]) {
      __pyx_v_cx = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_cx == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L3_error)
    } else {
      __pyx_v_cx = ((float)-1.0);
    }
    if (values[2]) {
      __pyx_v_cy = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_cy == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L3_error)
    } else {
      __pyx_v_cy = ((float)-1.0);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("rotate", 0, 1, 3, __pyx_nargs); __PYX_ERR(0, 181, __pyx_L3_error)
  goto __pyx_L3_error;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.rotate", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_10rotate(((struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self), __pyx_v_angle, __pyx_v_cx, __pyx_v_cy);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyArrayObject *__pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_10rotate(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, float __pyx_v_angle, float __pyx_v_cx, float __pyx_v_cy) {
  __Pyx_memviewslice __pyx_v_imRotated = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyArrayObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("rotate", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_3, 1);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.rotate", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_imRotated, 1);
  __Pyx_XGIVEREF((PyObject *)__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__31 = PyTuple_Pack(5, __pyx_n_s_self, __pyx_n_s_angle, __pyx_n_s_cx, __pyx_n_s_cy, __pyx_n_s_imRotated); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(0, 181, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__31);
  __Pyx_GIVEREF(__pyx_tuple__31);
  __pyx_codeobj__32 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__31, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_nanopyx_core_transform_inter, __pyx_n_s_rotate, 181, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__32)) __PYX_ERR(0, 181, __pyx_L1_error)
/* … */
  __pyx_t_7 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 181, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_return, __pyx_kp_s_np_ndarray) < 0) __PYX_ERR(0, 181, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_11rotate, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Interpolator_rotate, NULL, __pyx_n_s_nanopyx_core_transform_interpola, __pyx_d, ((PyObject *)__pyx_codeobj__32)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 181, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_tuple__33);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_7);
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator, __pyx_n_s_rotate, __pyx_t_4) < 0) __PYX_ERR(0, 181, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  PyType_Modified(__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator);
  __pyx_tuple__33 = PyTuple_Pack(2, __pyx_float_neg_1_0, __pyx_float_neg_1_0); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(0, 181, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__33);
  __Pyx_GIVEREF(__pyx_tuple__33);
 182:         """
 183:         Rotate an image by angle radians around (cx,cy) using interpolation
 184:         :param angle: rotation angle in radians, positive angles are counter clockwise
 185:         :param cx: x coordinate of the center of rotation, defaults to image center if negative
 186:         :param cy: y coordinate of the center of rotation, defaults to image center if negative
 187:         """
+188:         if cx<0 or cy<0:
  __pyx_t_2 = (__pyx_v_cx < 0.0);
  if (!__pyx_t_2) {
  } else {
    __pyx_t_1 = __pyx_t_2;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_2 = (__pyx_v_cy < 0.0);
  __pyx_t_1 = __pyx_t_2;
  __pyx_L4_bool_binop_done:;
  if (__pyx_t_1) {
/* … */
  }
+189:             cx = self.w / 2
    __pyx_v_cx = (((long)__pyx_v_self->w) / 2);
+190:             cy = self.h / 2
    __pyx_v_cy = (((long)__pyx_v_self->h) / 2);
 191: 
+192:         imRotated = self._rotate(angle, cx, cy)
  __pyx_t_3 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_rotate(__pyx_v_self, __pyx_v_angle, __pyx_v_cx, __pyx_v_cy); if (unlikely(!__pyx_t_3.memview)) __PYX_ERR(0, 192, __pyx_L1_error)
  __pyx_v_imRotated = __pyx_t_3;
  __pyx_t_3.memview = NULL;
  __pyx_t_3.data = NULL;
+193:         return np.asarray(imRotated).astype(self.original_dtype)
  __Pyx_XDECREF((PyObject *)__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_np); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 193, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_asarray); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 193, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_6 = __pyx_memoryview_fromslice(__pyx_v_imRotated, 2, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 193, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_8 = NULL;
  __pyx_t_9 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_7))) {
    __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
    if (likely(__pyx_t_8)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
      __Pyx_INCREF(__pyx_t_8);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_7, function);
      __pyx_t_9 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_8, __pyx_t_6};
    __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_7, __pyx_callargs+1-__pyx_t_9, 1+__pyx_t_9);
    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 193, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  }
  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_astype); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 193, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = NULL;
  __pyx_t_9 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_7))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_7);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_7, function);
      __pyx_t_9 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_self->original_dtype};
    __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_7, __pyx_callargs+1-__pyx_t_9, 1+__pyx_t_9);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 193, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  }
  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 193, __pyx_L1_error)
  __pyx_r = ((PyArrayObject *)__pyx_t_4);
  __pyx_t_4 = 0;
  goto __pyx_L0;
 194: 
 195: 
+196:     cdef float[:,:] _rotate(self, float angle, float cx, float cy):
static __Pyx_memviewslice __pyx_f_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator__rotate(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, float __pyx_v_angle, float __pyx_v_cx, float __pyx_v_cy) {
  __Pyx_memviewslice __pyx_v_imRotated = { 0, 0, { 0 }, { 0 }, { 0 } };
  int __pyx_v_i;
  int __pyx_v_j;
  float __pyx_v_rotx;
  float __pyx_v_roty;
  float __pyx_v_cosine;
  float __pyx_v_sine;
  __Pyx_memviewslice __pyx_r = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_rotate", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_6, 1);
  __pyx_r.data = NULL;
  __pyx_r.memview = NULL;
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator._rotate", __pyx_clineno, __pyx_lineno, __pyx_filename);
  goto __pyx_L2;
  __pyx_L0:;
  if (unlikely(!__pyx_r.memview)) {
    PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");
  }
  __pyx_L2:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_imRotated, 1);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 197: 
+198:         cdef float[:,:] imRotated = np.zeros((self.h, self.w), dtype=np.float32)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->h); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_self->w); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1)) __PYX_ERR(0, 198, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_3);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3)) __PYX_ERR(0, 198, __pyx_L1_error);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4)) __PYX_ERR(0, 198, __pyx_L1_error);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_float(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_imRotated = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
 199: 
 200:         cdef int i, j
 201:         cdef float rotx, roty
 202: 
+203:         cdef float cosine = cos(angle)
  __pyx_v_cosine = cos(__pyx_v_angle);
+204:         cdef float sine = sin(angle)
  __pyx_v_sine = sin(__pyx_v_angle);
 205: 
+206:         with nogil:
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      _save = NULL;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L5;
        }
        __pyx_L4_error: {
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L1_error;
        }
        __pyx_L5:;
      }
  }
+207:             for i in prange(0, self.w):
        __pyx_t_7 = __pyx_v_self->w;
        {
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   (x)
                #define unlikely(x) (x)
            #endif
            __pyx_t_9 = (__pyx_t_7 - 0 + 1 - 1/abs(1)) / 1;
            if (__pyx_t_9 > 0)
            {
                #ifdef _OPENMP
                #pragma omp parallel
                #endif /* _OPENMP */
                {
                    #ifdef _OPENMP
                    #pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_j) lastprivate(__pyx_v_rotx) lastprivate(__pyx_v_roty)
                    #endif /* _OPENMP */
                    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_9; __pyx_t_8++){
                        {
                            __pyx_v_i = (int)(0 + 1 * __pyx_t_8);
                            /* Initialize private variables to invalid values */
                            __pyx_v_j = ((int)0xbad0bad0);
                            __pyx_v_rotx = ((float)__PYX_NAN());
                            __pyx_v_roty = ((float)__PYX_NAN());
+208:                 for j in range(0, self.h):
                            __pyx_t_10 = __pyx_v_self->h;
                            __pyx_t_11 = __pyx_t_10;
                            for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
                              __pyx_v_j = __pyx_t_12;
+209:                     rotx = cosine*(i-cx) - sine*(j-cy) + cx
                              __pyx_v_rotx = (((__pyx_v_cosine * (__pyx_v_i - __pyx_v_cx)) - (__pyx_v_sine * (__pyx_v_j - __pyx_v_cy))) + __pyx_v_cx);
+210:                     roty = sine*(i-cx) + cosine*(j-cy) + cy
                              __pyx_v_roty = (((__pyx_v_sine * (__pyx_v_i - __pyx_v_cx)) + (__pyx_v_cosine * (__pyx_v_j - __pyx_v_cy))) + __pyx_v_cy);
+211:                     imRotated[j,i] = self._interpolate(rotx,roty)
                              __pyx_t_13 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_interpolate(__pyx_v_self, __pyx_v_rotx, __pyx_v_roty); if (unlikely(__Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 211, __pyx_L8_error)
                              __pyx_t_14 = __pyx_v_j;
                              __pyx_t_15 = __pyx_v_i;
                              *((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_imRotated.data + __pyx_t_14 * __pyx_v_imRotated.strides[0]) ) + __pyx_t_15 * __pyx_v_imRotated.strides[1]) )) = __pyx_t_13;
                            }
                            goto __pyx_L13;
                            __pyx_L8_error:;
                            {
                                #ifdef WITH_THREAD
                                PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                                #endif
                                #ifdef _OPENMP
                                #pragma omp flush(__pyx_parallel_exc_type)
                                #endif /* _OPENMP */
                                if (!__pyx_parallel_exc_type) {
                                  __Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb);
                                  __pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno;
                                  __Pyx_GOTREF(__pyx_parallel_exc_type);
                                }
                                #ifdef WITH_THREAD
                                __Pyx_PyGILState_Release(__pyx_gilstate_save);
                                #endif
                            }
                            __pyx_parallel_why = 4;
                            goto __pyx_L12;
                            __pyx_L12:;
                            #ifdef _OPENMP
                            #pragma omp critical(__pyx_parallel_lastprivates12)
                            #endif /* _OPENMP */
                            {
                                __pyx_parallel_temp0 = __pyx_v_i;
                                __pyx_parallel_temp1 = __pyx_v_j;
                                __pyx_parallel_temp2 = __pyx_v_rotx;
                                __pyx_parallel_temp3 = __pyx_v_roty;
                            }
                            __pyx_L13:;
                            #ifdef _OPENMP
                            #pragma omp flush(__pyx_parallel_why)
                            #endif /* _OPENMP */
                        }
                    }
                    #ifdef _OPENMP
                    Py_END_ALLOW_THREADS
                    #else
{
#ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    #endif /* _OPENMP */
                    /* Clean up any temporaries */
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                    #ifndef _OPENMP
}
#endif /* _OPENMP */
                }
            }
            if (__pyx_parallel_exc_type) {
              /* This may have been overridden by a continue, break or return in another thread. Prefer the error. */
              __pyx_parallel_why = 4;
            }
            if (__pyx_parallel_why) {
              __pyx_v_i = __pyx_parallel_temp0;
              __pyx_v_j = __pyx_parallel_temp1;
              __pyx_v_rotx = __pyx_parallel_temp2;
              __pyx_v_roty = __pyx_parallel_temp3;
              switch (__pyx_parallel_why) {
                    case 4:
                {
                    #ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    __Pyx_GIVEREF(__pyx_parallel_exc_type);
                    __Pyx_ErrRestoreWithState(__pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb);
                    __pyx_filename = __pyx_parallel_filename; __pyx_lineno = __pyx_parallel_lineno; __pyx_clineno = __pyx_parallel_clineno;
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                }
                goto __pyx_L4_error;
              }
            }
        }
        #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
            #undef likely
            #undef unlikely
            #define likely(x)   __builtin_expect(!!(x), 1)
            #define unlikely(x) __builtin_expect(!!(x), 0)
        #endif
      }
 212: 
+213:         return imRotated
  __PYX_INC_MEMVIEW(&__pyx_v_imRotated, 1);
  __pyx_r = __pyx_v_imRotated;
  goto __pyx_L0;
 214: 
+215:     def polar(self, str scale="linear") -> np.ndarray:
/* Python wrapper */
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_13polar(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_12polar, "\n        Transforms an image into its polar coordinate equivalent with origin at the center of the image\n        :param scale: scaling done during conversion, if 'log' performs log-polar transformation\n        :return: (theta,r) image array\n        ");
static PyMethodDef __pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_13polar = {"polar", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_13polar, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_12polar};
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_13polar(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_scale = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyArrayObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("polar (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args);
  if (unlikely((__pyx_nargs < 0))) __PYX_ERR(0, 215, __pyx_L3_error)
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scale,0};
  PyObject* values[1] = {0};
    values[0] = __Pyx_Arg_NewRef_FASTCALL(((PyObject*)__pyx_n_u_linear));
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (kw_args > 0) {
          PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_scale);
          if (value) { values[0] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; }
          else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 215, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "polar") < 0)) __PYX_ERR(0, 215, __pyx_L3_error)
      }
    } else {
      switch (__pyx_nargs) {
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_scale = ((PyObject*)values[0]);
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("polar", 0, 0, 1, __pyx_nargs); __PYX_ERR(0, 215, __pyx_L3_error)
  goto __pyx_L3_error;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.polar", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_scale), (&PyUnicode_Type), 1, "scale", 1))) __PYX_ERR(0, 215, __pyx_L1_error)
  __pyx_r = __pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_12polar(((struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self), __pyx_v_scale);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyArrayObject *__pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_12polar(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, PyObject *__pyx_v_scale) {
  __Pyx_memviewslice __pyx_v_polarized = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyArrayObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("polar", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_1, 1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.polar", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_polarized, 1);
  __Pyx_XGIVEREF((PyObject *)__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__34 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_scale, __pyx_n_s_polarized); if (unlikely(!__pyx_tuple__34)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__34);
  __Pyx_GIVEREF(__pyx_tuple__34);
  __pyx_codeobj__35 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__34, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_nanopyx_core_transform_inter, __pyx_n_s_polar, 215, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__35)) __PYX_ERR(0, 215, __pyx_L1_error)
/* … */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_kp_s_np_ndarray) < 0) __PYX_ERR(0, 215, __pyx_L1_error)
  __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_13polar, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Interpolator_polar, NULL, __pyx_n_s_nanopyx_core_transform_interpola, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_7, __pyx_tuple__36);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_7, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator, __pyx_n_s_polar, __pyx_t_7) < 0) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  PyType_Modified(__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator);
  __pyx_tuple__36 = PyTuple_Pack(1, __pyx_n_u_linear); if (unlikely(!__pyx_tuple__36)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__36);
  __Pyx_GIVEREF(__pyx_tuple__36);
 216:         """
 217:         Transforms an image into its polar coordinate equivalent with origin at the center of the image
 218:         :param scale: scaling done during conversion, if 'log' performs log-polar transformation
 219:         :return: (theta,r) image array
 220:         """
+221:         polarized = self._polar(scale)
  __pyx_t_1 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_polar(__pyx_v_self, __pyx_v_scale); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 221, __pyx_L1_error)
  __pyx_v_polarized = __pyx_t_1;
  __pyx_t_1.memview = NULL;
  __pyx_t_1.data = NULL;
+222:         return np.asarray(polarized).astype(self.original_dtype)
  __Pyx_XDECREF((PyObject *)__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 222, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 222, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_polarized, 2, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 222, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_t_4};
    __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 222, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_astype); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 222, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_self->original_dtype};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 222, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 222, __pyx_L1_error)
  __pyx_r = ((PyArrayObject *)__pyx_t_2);
  __pyx_t_2 = 0;
  goto __pyx_L0;
 223: 
+224:     cdef float[:,:] _polar(self, str scale):
static __Pyx_memviewslice __pyx_f_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator__polar(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, PyObject *__pyx_v_scale) {
  float __pyx_v_cx;
  float __pyx_v_cy;
  int __pyx_v_max_theta;
  int __pyx_v_max_radius;
  __Pyx_memviewslice __pyx_v_polarized = { 0, 0, { 0 }, { 0 }, { 0 } };
  int __pyx_v_i;
  int __pyx_v_j;
  float __pyx_v_x;
  float __pyx_v_y;
  __Pyx_memviewslice __pyx_r = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_polar", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_7, 1);
  __pyx_r.data = NULL;
  __pyx_r.memview = NULL;
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator._polar", __pyx_clineno, __pyx_lineno, __pyx_filename);
  goto __pyx_L2;
  __pyx_L0:;
  if (unlikely(!__pyx_r.memview)) {
    PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");
  }
  __pyx_L2:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_polarized, 1);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 225: 
+226:         cdef float cx = self.w / 2
  __pyx_v_cx = (((long)__pyx_v_self->w) / 2);
+227:         cdef float cy = self.h / 2
  __pyx_v_cy = (((long)__pyx_v_self->h) / 2);
 228: 
+229:         cdef int max_theta = 360
  __pyx_v_max_theta = 0x168;
+230:         cdef int max_radius = int(hypot(cx,cy))+1
  __pyx_t_1 = __Pyx_PyInt_FromDouble(hypot(__pyx_v_cx, __pyx_v_cy)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 230, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyInt_AddObjC(__pyx_t_1, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 230, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 230, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_max_radius = __pyx_t_3;
 231: 
+232:         cdef float[:,:] polarized = np.zeros((max_theta, max_radius), dtype=np.float32)
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_max_theta); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_max_radius); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_GIVEREF(__pyx_t_2);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_4);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4)) __PYX_ERR(0, 232, __pyx_L1_error);
  __pyx_t_2 = 0;
  __pyx_t_4 = 0;
  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_5);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5)) __PYX_ERR(0, 232, __pyx_L1_error);
  __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_float32); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_6) < 0) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dsds_float(__pyx_t_6, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_v_polarized = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 233: 
 234:         cdef int i,j
 235:         cdef float x,y
 236: 
+237:         with nogil:
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      _save = NULL;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L5;
        }
        __pyx_L4_error: {
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L1_error;
        }
        __pyx_L5:;
      }
  }
+238:             for i in prange(0,max_radius):
        __pyx_t_3 = __pyx_v_max_radius;
        {
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   (x)
                #define unlikely(x) (x)
            #endif
            __pyx_t_9 = (__pyx_t_3 - 0 + 1 - 1/abs(1)) / 1;
            if (__pyx_t_9 > 0)
            {
                #ifdef _OPENMP
                #pragma omp parallel
                #endif /* _OPENMP */
                {
                    #ifdef _OPENMP
                    #pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_j) lastprivate(__pyx_v_x) lastprivate(__pyx_v_y)
                    #endif /* _OPENMP */
                    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_9; __pyx_t_8++){
                        {
                            __pyx_v_i = (int)(0 + 1 * __pyx_t_8);
                            /* Initialize private variables to invalid values */
                            __pyx_v_j = ((int)0xbad0bad0);
                            __pyx_v_x = ((float)__PYX_NAN());
                            __pyx_v_y = ((float)__PYX_NAN());
+239:                 for j in range(0,max_theta):
                            __pyx_t_10 = __pyx_v_max_theta;
                            __pyx_t_11 = __pyx_t_10;
                            for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
                              __pyx_v_j = __pyx_t_12;
+240:                     if scale=="log":
                              __pyx_t_13 = (__Pyx_PyUnicode_Equals(__pyx_v_scale, __pyx_n_u_log, Py_EQ)); if (unlikely((__pyx_t_13 < 0))) __PYX_ERR(0, 240, __pyx_L8_error)
                              if (__pyx_t_13) {
/* … */
                                goto __pyx_L12;
                              }
+241:                         x = exp(i*log(max_radius)/max_radius) * cos(j*pi/180) + cx
                                __pyx_v_x = ((exp(((__pyx_v_i * log(__pyx_v_max_radius)) / ((double)__pyx_v_max_radius))) * cos(((__pyx_v_j * M_PI) / 180.0))) + __pyx_v_cx);
+242:                         y = exp(i*log(max_radius)/max_radius) * sin(j*pi/180) + cy
                                __pyx_v_y = ((exp(((__pyx_v_i * log(__pyx_v_max_radius)) / ((double)__pyx_v_max_radius))) * sin(((__pyx_v_j * M_PI) / 180.0))) + __pyx_v_cy);
 243:                     else:
+244:                         x = i * cos(j*pi/180) + cx
                              /*else*/ {
                                __pyx_v_x = ((__pyx_v_i * cos(((__pyx_v_j * M_PI) / 180.0))) + __pyx_v_cx);
+245:                         y = i * sin(j*pi/180) + cy
                                __pyx_v_y = ((__pyx_v_i * sin(((__pyx_v_j * M_PI) / 180.0))) + __pyx_v_cy);
                              }
                              __pyx_L12:;
+246:                     polarized[j,i] = self._interpolate(x,y)
                              __pyx_t_14 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_interpolate(__pyx_v_self, __pyx_v_x, __pyx_v_y); if (unlikely(__Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 246, __pyx_L8_error)
                              __pyx_t_15 = __pyx_v_j;
                              __pyx_t_16 = __pyx_v_i;
                              *((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_polarized.data + __pyx_t_15 * __pyx_v_polarized.strides[0]) ) + __pyx_t_16 * __pyx_v_polarized.strides[1]) )) = __pyx_t_14;
                            }
                            goto __pyx_L14;
                            __pyx_L8_error:;
                            {
                                #ifdef WITH_THREAD
                                PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                                #endif
                                #ifdef _OPENMP
                                #pragma omp flush(__pyx_parallel_exc_type)
                                #endif /* _OPENMP */
                                if (!__pyx_parallel_exc_type) {
                                  __Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb);
                                  __pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno;
                                  __Pyx_GOTREF(__pyx_parallel_exc_type);
                                }
                                #ifdef WITH_THREAD
                                __Pyx_PyGILState_Release(__pyx_gilstate_save);
                                #endif
                            }
                            __pyx_parallel_why = 4;
                            goto __pyx_L13;
                            __pyx_L13:;
                            #ifdef _OPENMP
                            #pragma omp critical(__pyx_parallel_lastprivates13)
                            #endif /* _OPENMP */
                            {
                                __pyx_parallel_temp0 = __pyx_v_i;
                                __pyx_parallel_temp1 = __pyx_v_j;
                                __pyx_parallel_temp2 = __pyx_v_x;
                                __pyx_parallel_temp3 = __pyx_v_y;
                            }
                            __pyx_L14:;
                            #ifdef _OPENMP
                            #pragma omp flush(__pyx_parallel_why)
                            #endif /* _OPENMP */
                        }
                    }
                    #ifdef _OPENMP
                    Py_END_ALLOW_THREADS
                    #else
{
#ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    #endif /* _OPENMP */
                    /* Clean up any temporaries */
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                    #ifndef _OPENMP
}
#endif /* _OPENMP */
                }
            }
            if (__pyx_parallel_exc_type) {
              /* This may have been overridden by a continue, break or return in another thread. Prefer the error. */
              __pyx_parallel_why = 4;
            }
            if (__pyx_parallel_why) {
              __pyx_v_i = __pyx_parallel_temp0;
              __pyx_v_j = __pyx_parallel_temp1;
              __pyx_v_x = __pyx_parallel_temp2;
              __pyx_v_y = __pyx_parallel_temp3;
              switch (__pyx_parallel_why) {
                    case 4:
                {
                    #ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    __Pyx_GIVEREF(__pyx_parallel_exc_type);
                    __Pyx_ErrRestoreWithState(__pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb);
                    __pyx_filename = __pyx_parallel_filename; __pyx_lineno = __pyx_parallel_lineno; __pyx_clineno = __pyx_parallel_clineno;
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                }
                goto __pyx_L4_error;
              }
            }
        }
        #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
            #undef likely
            #undef unlikely
            #define likely(x)   __builtin_expect(!!(x), 1)
            #define unlikely(x) __builtin_expect(!!(x), 0)
        #endif
      }
 247: 
+248:         return polarized
  __PYX_INC_MEMVIEW(&__pyx_v_polarized, 1);
  __pyx_r = __pyx_v_polarized;
  goto __pyx_L0;
 249: 
+250:     def cartesian(self, int x_shape, int y_shape, str scale="linear")-> np.ndarray:
/* Python wrapper */
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_15cartesian(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_14cartesian, "\n        Transforms an image into its cartesian coordinate equivalent. Assumes image shape is (theta,r) and the origin is at the center of the cartesian image\n        :param x_shape: width of original image\n        :param y_shape: height of original image\n        :param scale: scaling performed during transition to polar coordinates, if 'log' assumes the image was a log-polar image\n        :return: (y,x) image array\n        ");
static PyMethodDef __pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_15cartesian = {"cartesian", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_15cartesian, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_14cartesian};
static PyArrayObject *__pyx_pw_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_15cartesian(PyObject *__pyx_v_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  int __pyx_v_x_shape;
  int __pyx_v_y_shape;
  PyObject *__pyx_v_scale = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyArrayObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("cartesian (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args);
  if (unlikely((__pyx_nargs < 0))) __PYX_ERR(0, 250, __pyx_L3_error)
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x_shape,&__pyx_n_s_y_shape,&__pyx_n_s_scale,0};
  PyObject* values[3] = {0,0,0};
    values[2] = __Pyx_Arg_NewRef_FASTCALL(((PyObject*)__pyx_n_u_linear));
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_x_shape)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 250, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_y_shape)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 250, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("cartesian", 0, 2, 3, 1); __PYX_ERR(0, 250, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_scale);
          if (value) { values[2] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; }
          else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 250, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "cartesian") < 0)) __PYX_ERR(0, 250, __pyx_L3_error)
      }
    } else {
      switch (__pyx_nargs) {
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_x_shape = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_x_shape == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 250, __pyx_L3_error)
    __pyx_v_y_shape = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_y_shape == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 250, __pyx_L3_error)
    __pyx_v_scale = ((PyObject*)values[2]);
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("cartesian", 0, 2, 3, __pyx_nargs); __PYX_ERR(0, 250, __pyx_L3_error)
  goto __pyx_L3_error;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.cartesian", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_scale), (&PyUnicode_Type), 1, "scale", 1))) __PYX_ERR(0, 250, __pyx_L1_error)
  __pyx_r = __pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_14cartesian(((struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self), __pyx_v_x_shape, __pyx_v_y_shape, __pyx_v_scale);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyArrayObject *__pyx_pf_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_14cartesian(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, int __pyx_v_x_shape, int __pyx_v_y_shape, PyObject *__pyx_v_scale) {
  __Pyx_memviewslice __pyx_v_cart = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyArrayObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("cartesian", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_1, 1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator.cartesian", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_cart, 1);
  __Pyx_XGIVEREF((PyObject *)__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__37 = PyTuple_Pack(5, __pyx_n_s_self, __pyx_n_s_x_shape, __pyx_n_s_y_shape, __pyx_n_s_scale, __pyx_n_s_cart); if (unlikely(!__pyx_tuple__37)) __PYX_ERR(0, 250, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__37);
  __Pyx_GIVEREF(__pyx_tuple__37);
/* … */
  __pyx_t_7 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 250, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_return, __pyx_kp_s_np_ndarray) < 0) __PYX_ERR(0, 250, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator_15cartesian, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Interpolator_cartesian, NULL, __pyx_n_s_nanopyx_core_transform_interpola, __pyx_d, ((PyObject *)__pyx_codeobj__38)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 250, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_tuple__36);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_7);
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator, __pyx_n_s_cartesian, __pyx_t_4) < 0) __PYX_ERR(0, 250, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  PyType_Modified(__pyx_ptype_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator);
  __pyx_codeobj__38 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__37, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_nanopyx_core_transform_inter, __pyx_n_s_cartesian, 250, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__38)) __PYX_ERR(0, 250, __pyx_L1_error)
 251:         """
 252:         Transforms an image into its cartesian coordinate equivalent. Assumes image shape is (theta,r) and the origin is at the center of the cartesian image
 253:         :param x_shape: width of original image
 254:         :param y_shape: height of original image
 255:         :param scale: scaling performed during transition to polar coordinates, if 'log' assumes the image was a log-polar image
 256:         :return: (y,x) image array
 257:         """
+258:         cart = self._cartesian(x_shape, y_shape, scale)
  __pyx_t_1 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_cartesian(__pyx_v_self, __pyx_v_x_shape, __pyx_v_y_shape, __pyx_v_scale); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 258, __pyx_L1_error)
  __pyx_v_cart = __pyx_t_1;
  __pyx_t_1.memview = NULL;
  __pyx_t_1.data = NULL;
+259:         return np.asarray(cart).astype(self.original_dtype)
  __Pyx_XDECREF((PyObject *)__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 259, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 259, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_cart, 2, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 259, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_t_4};
    __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 259, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_astype); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 259, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_self->original_dtype};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 259, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 259, __pyx_L1_error)
  __pyx_r = ((PyArrayObject *)__pyx_t_2);
  __pyx_t_2 = 0;
  goto __pyx_L0;
 260: 
+261:     cdef float[:,:] _cartesian(self, int x_shape, int y_shape, str scale):
static __Pyx_memviewslice __pyx_f_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_12Interpolator__cartesian(struct __pyx_obj_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *__pyx_v_self, int __pyx_v_x_shape, int __pyx_v_y_shape, PyObject *__pyx_v_scale) {
  __Pyx_memviewslice __pyx_v_cart = { 0, 0, { 0 }, { 0 }, { 0 } };
  float __pyx_v_cx;
  float __pyx_v_cy;
  int __pyx_v_i;
  int __pyx_v_j;
  float __pyx_v_r;
  float __pyx_v_t;
  __Pyx_memviewslice __pyx_r = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_cartesian", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_6, 1);
  __pyx_r.data = NULL;
  __pyx_r.memview = NULL;
  __Pyx_AddTraceback("nanopyx.core.transform.interpolation_nearest_neighbor.Interpolator._cartesian", __pyx_clineno, __pyx_lineno, __pyx_filename);
  goto __pyx_L2;
  __pyx_L0:;
  if (unlikely(!__pyx_r.memview)) {
    PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");
  }
  __pyx_L2:;
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_cart, 1);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 262: 
+263:         cdef float[:,:] cart = np.zeros((y_shape, x_shape), dtype=np.float32)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_y_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_x_shape); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1)) __PYX_ERR(0, 263, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_3);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3)) __PYX_ERR(0, 263, __pyx_L1_error);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4)) __PYX_ERR(0, 263, __pyx_L1_error);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_float(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 263, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_cart = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
 264: 
+265:         cdef float cx = x_shape / 2
  __pyx_v_cx = (((long)__pyx_v_x_shape) / 2);
+266:         cdef float cy = y_shape / 2
  __pyx_v_cy = (((long)__pyx_v_y_shape) / 2);
 267: 
 268:         cdef int i, j
 269:         cdef float r, t
+270:         with nogil:
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      _save = NULL;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L5;
        }
        __pyx_L4_error: {
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L1_error;
        }
        __pyx_L5:;
      }
  }
+271:             for i in prange(0,x_shape):
        __pyx_t_7 = __pyx_v_x_shape;
        {
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   (x)
                #define unlikely(x) (x)
            #endif
            __pyx_t_9 = (__pyx_t_7 - 0 + 1 - 1/abs(1)) / 1;
            if (__pyx_t_9 > 0)
            {
                #ifdef _OPENMP
                #pragma omp parallel
                #endif /* _OPENMP */
                {
                    #ifdef _OPENMP
                    #pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_j) lastprivate(__pyx_v_r) lastprivate(__pyx_v_t)
                    #endif /* _OPENMP */
                    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_9; __pyx_t_8++){
                        {
                            __pyx_v_i = (int)(0 + 1 * __pyx_t_8);
                            /* Initialize private variables to invalid values */
                            __pyx_v_j = ((int)0xbad0bad0);
                            __pyx_v_r = ((float)__PYX_NAN());
                            __pyx_v_t = ((float)__PYX_NAN());
+272:                 for j in range(0,y_shape):
                            __pyx_t_10 = __pyx_v_y_shape;
                            __pyx_t_11 = __pyx_t_10;
                            for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
                              __pyx_v_j = __pyx_t_12;
+273:                     if scale=="log" and (j!=cy and i!=cx):
                              __pyx_t_14 = (__Pyx_PyUnicode_Equals(__pyx_v_scale, __pyx_n_u_log, Py_EQ)); if (unlikely((__pyx_t_14 < 0))) __PYX_ERR(0, 273, __pyx_L8_error)
                              if (__pyx_t_14) {
                              } else {
                                __pyx_t_13 = __pyx_t_14;
                                goto __pyx_L13_bool_binop_done;
                              }
                              __pyx_t_14 = (__pyx_v_j != __pyx_v_cy);
                              if (__pyx_t_14) {
                              } else {
                                __pyx_t_13 = __pyx_t_14;
                                goto __pyx_L13_bool_binop_done;
                              }
                              __pyx_t_14 = (__pyx_v_i != __pyx_v_cx);
                              __pyx_t_13 = __pyx_t_14;
                              __pyx_L13_bool_binop_done:;
                              if (__pyx_t_13) {
/* … */
                                goto __pyx_L12;
                              }
+274:                         r = log(hypot(j-cy,i-cx)) * self.w / log(self.w)
                                __pyx_v_r = ((log(hypot((__pyx_v_j - __pyx_v_cy), (__pyx_v_i - __pyx_v_cx))) * __pyx_v_self->w) / log(__pyx_v_self->w));
 275:                     else:
+276:                         r = hypot(j-cy, i-cx)
                              /*else*/ {
                                __pyx_v_r = hypot((__pyx_v_j - __pyx_v_cy), (__pyx_v_i - __pyx_v_cx));
                              }
                              __pyx_L12:;
+277:                     t = atan2(j-cy,i-cx) * 180/pi
                              __pyx_v_t = ((atan2((__pyx_v_j - __pyx_v_cy), (__pyx_v_i - __pyx_v_cx)) * 180.0) / ((double)M_PI));
+278:                     if t<0:
                              __pyx_t_13 = (__pyx_v_t < 0.0);
                              if (__pyx_t_13) {
/* … */
                              }
+279:                         t = 360+t
                                __pyx_v_t = (360.0 + __pyx_v_t);
+280:                     cart[j,i] = self._interpolate(r,t)
                              __pyx_t_15 = ((struct __pyx_vtabstruct_7nanopyx_4core_9transform_30interpolation_nearest_neighbor_Interpolator *)__pyx_v_self->__pyx_vtab)->_interpolate(__pyx_v_self, __pyx_v_r, __pyx_v_t); if (unlikely(__Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 280, __pyx_L8_error)
                              __pyx_t_16 = __pyx_v_j;
                              __pyx_t_17 = __pyx_v_i;
                              *((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_cart.data + __pyx_t_16 * __pyx_v_cart.strides[0]) ) + __pyx_t_17 * __pyx_v_cart.strides[1]) )) = __pyx_t_15;
                            }
                            goto __pyx_L18;
                            __pyx_L8_error:;
                            {
                                #ifdef WITH_THREAD
                                PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                                #endif
                                #ifdef _OPENMP
                                #pragma omp flush(__pyx_parallel_exc_type)
                                #endif /* _OPENMP */
                                if (!__pyx_parallel_exc_type) {
                                  __Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb);
                                  __pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno;
                                  __Pyx_GOTREF(__pyx_parallel_exc_type);
                                }
                                #ifdef WITH_THREAD
                                __Pyx_PyGILState_Release(__pyx_gilstate_save);
                                #endif
                            }
                            __pyx_parallel_why = 4;
                            goto __pyx_L17;
                            __pyx_L17:;
                            #ifdef _OPENMP
                            #pragma omp critical(__pyx_parallel_lastprivates14)
                            #endif /* _OPENMP */
                            {
                                __pyx_parallel_temp0 = __pyx_v_i;
                                __pyx_parallel_temp1 = __pyx_v_j;
                                __pyx_parallel_temp2 = __pyx_v_r;
                                __pyx_parallel_temp3 = __pyx_v_t;
                            }
                            __pyx_L18:;
                            #ifdef _OPENMP
                            #pragma omp flush(__pyx_parallel_why)
                            #endif /* _OPENMP */
                        }
                    }
                    #ifdef _OPENMP
                    Py_END_ALLOW_THREADS
                    #else
{
#ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    #endif /* _OPENMP */
                    /* Clean up any temporaries */
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                    #ifndef _OPENMP
}
#endif /* _OPENMP */
                }
            }
            if (__pyx_parallel_exc_type) {
              /* This may have been overridden by a continue, break or return in another thread. Prefer the error. */
              __pyx_parallel_why = 4;
            }
            if (__pyx_parallel_why) {
              __pyx_v_i = __pyx_parallel_temp0;
              __pyx_v_j = __pyx_parallel_temp1;
              __pyx_v_r = __pyx_parallel_temp2;
              __pyx_v_t = __pyx_parallel_temp3;
              switch (__pyx_parallel_why) {
                    case 4:
                {
                    #ifdef WITH_THREAD
                    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
                    #endif
                    __Pyx_GIVEREF(__pyx_parallel_exc_type);
                    __Pyx_ErrRestoreWithState(__pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb);
                    __pyx_filename = __pyx_parallel_filename; __pyx_lineno = __pyx_parallel_lineno; __pyx_clineno = __pyx_parallel_clineno;
                    #ifdef WITH_THREAD
                    __Pyx_PyGILState_Release(__pyx_gilstate_save);
                    #endif
                }
                goto __pyx_L4_error;
              }
            }
        }
        #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
            #undef likely
            #undef unlikely
            #define likely(x)   __builtin_expect(!!(x), 1)
            #define unlikely(x) __builtin_expect(!!(x), 0)
        #endif
      }
 281: 
+282:         return cart
  __PYX_INC_MEMVIEW(&__pyx_v_cart, 1);
  __pyx_r = __pyx_v_cart;
  goto __pyx_L0;